//
//  CGContext+AG.swift
//  BWExtensionKit
//
//  Created by zhuxuhong on 2022/2/23.
//

import UIKit

extension CGContext {
    public enum PointPosition: Int {
        public typealias Group = (x: PointPosition, y: PointPosition)
        
        case min = 0, max
        
        public static func point(for group: Group, in rect: CGRect) -> CGPoint {
            switch group {
            case (.min, .min):
                return .init(x: rect.minX, y: rect.minY)
            case (.min, .max):
                return .init(x: rect.minX, y: rect.maxY)
            case (.max, .min):
                return .init(x: rect.maxX, y: rect.minY)
            case (.max, .max):
                return .init(x: rect.maxY, y: rect.maxY)
            }
        }
    }
    
    public func bw_drawLinearGradient(
        in rect: CGRect,
        start: PointPosition.Group = (x: .min, y: .min),
        end: PointPosition.Group = (x: .min, y: .max),
        locationAndColors: [CGFloat: UIColor]
    ){
        let lcs = locationAndColors.sorted{ $0.key < $1.key }
        let locations = lcs.map{ $0.key }
        let colors = lcs.map{ $0.value.cgColor } as CFArray
        
        let startPoint = PointPosition.point(for: start, in: rect)
        let endPoint = PointPosition.point(for: end, in: rect)
        
        guard let gradient = CGGradient.init(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors, locations: locations) else {
            return
        }
        
        saveGState()
        addRect(rect)
        clip()
        drawLinearGradient(gradient, start: startPoint, end: endPoint, options: .init())
        
        restoreGState()
    }
}
